package pe.com.certicom.ittsa.framework.dat;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import pe.com.certicom.ittsa.framework.dat.DaoUtil;
import pe.com.certicom.ittsa.framework.dat.Conexion;
import pe.com.certicom.ittsa.framework.exception.DaoException;

public class ConexionDaoUtil extends DaoUtil {
	private static final Log log = LogFactory.getLog(ConexionDaoUtil.class);
    
	public ConexionDaoUtil()throws DaoException{
		try{
			Conexion con =	new Conexion();
			conn		 = con.ObtenerConnection(); 
		}catch (Exception e) {
			 e.printStackTrace();				 
	            throw new DaoException("::: Error al crear la conexion a la base de datos ::: ", e);
		}
	}

    @SuppressWarnings("unchecked")
    public Object dato(String storeProcedure, Class clase, Object parametros[])throws DaoException{
        Object objDato = null;
        try {
        	objDato = super.dato(storeProcedure, clase, parametros);
        }  catch(Exception e){
            throw daoException(storeProcedure, "Error inesperado al obtener registro", e, parametros);
        }
        return objDato;
    }

    @SuppressWarnings("unchecked")
    public Object dato(String storeProcedure, Class clase) throws DaoException {
        Object objDato = null;
        try {
        	objDato = super.dato(storeProcedure, clase);
        } catch(Exception e) {
            throw daoException(storeProcedure, "Error al obtener un registro", e, null);
        }
        return objDato;
    }

    @SuppressWarnings("unchecked")
    public List datoLista(String storeProcedure, Class clase, Object parametros[]) throws DaoException {
        List listaDato = null;
        try{
            listaDato = super.datoLista(storeProcedure, clase, parametros);
        }catch(Exception e){
            throw daoException(storeProcedure, " ::: Error al obtener una lista de registros ::: ", e, parametros);
        }
        return listaDato;
    }

    @SuppressWarnings("unchecked")
    public List datoLista(String storeProcedure, Class clase)throws DaoException{
        List listaDato = null;
        try {
        	listaDato = super.datoLista(storeProcedure, clase);
        }catch(Exception e){
            throw daoException(storeProcedure, " ::: Error al obtener una lista de registros ::: ", e, null);
        }
        return listaDato;
    }

    public String tipoString(String storeProcedure, Object parametros[]) throws DaoException{
    	String obj = null;
    	try{
        obj = super.tipoString(storeProcedure, parametros);
    	}catch(Exception e){
        throw daoException(storeProcedure, "::: Error inesperado al obtener un valor ::: ", e, parametros);
    	}
    	return obj;
    }

    public Object executeScalar(String storeProcedure, Object parametros[])throws DaoException{
	
    	String sql = nombreStoreProcedure(storeProcedure, parametros.length);
    	Object respuesta=null;
    	try{
        setearVariableEntrada(sql, parametros);
        cstm.execute();
        rs = (ResultSet)cstm.getResultSet();
        rs.next();
        respuesta = rs.getString(1); 
    	}catch(SQLException e){
    	close();
    	log.fatal(" .. error ", e);
    	throw daoException(storeProcedure, e.getMessage(), e, parametros);
    	}
    	return respuesta; 
    }
  
    public Object[] execute(String storeProcedure, Object parametros[], int numeroParametrosOut)throws DaoException{
    
    	String sql = nombreStoreProcedure(storeProcedure, parametros.length + numeroParametrosOut);
    	Object respuesta[] = new Object[numeroParametrosOut];
    	try{
    		setearVariableEntrada(sql, parametros);
    		int numParametros = parametros.length;
    		for(int i = 0; i < numeroParametrosOut; i++)
    			cstm.registerOutParameter(numParametros + 1 + i, 12);
    			cstm.execute();
    		for(int i = 0; i < numeroParametrosOut; i++)
        	respuesta[i] = cstm.getObject(numParametros + 1 + i);
    	}catch(SQLException e){
        close();
        throw daoException(storeProcedure, " ::: Error al obtener varias variables de salida ::: ", e, parametros);
    }
    return respuesta;
}
    
    @SuppressWarnings("unchecked")
    public Object[] execute(String storeProcedure, Object parametros[], Class parametrosListSalida[])throws DaoException{
        return execute(storeProcedure, parametros, 0, parametrosListSalida);
    }  
    
    @SuppressWarnings("unchecked")
    public Object[] execute(String storeProcedure, Object parametros[], int numParametrosOut, Class parametrosListSalida[])throws DaoException{
        int numParametrosLista = parametrosListSalida.length;
        int numParametrosTotal = numParametrosOut + numParametrosLista;
        String sql = nombreStoreProcedure(storeProcedure, parametros.length + numParametrosTotal);
        Object respuesta[] = new Object[numParametrosTotal];
       
        try{
            setearVariableEntrada(sql, parametros);
            int numParametros = parametros.length;
            for(int i = 0; i < numParametrosOut; i++)
                cstm.registerOutParameter(numParametros + 1 + i, 12);

            for(int i = 0; i < numParametrosLista; i++)
                cstm.registerOutParameter(numParametros + numParametrosOut + 1 + i, -10);

            cstm.execute();
            for(int i = 0; i < numParametrosOut; i++)
                respuesta[i] = cstm.getObject(numParametros + 1 + i);

            for(int i = 0; i < numParametrosLista; i++){
                Object obj = cstm.getObject(numParametros + numParametrosOut + 1 + i);
                if(obj instanceof ResultSet)
                    respuesta[numParametrosOut + i] = obtenerDatoLista((ResultSet)obj, parametrosListSalida[i]);
                else
                    respuesta[numParametrosOut + i] = null;
            }

        }catch(SQLException e){
            close();
            throw daoException(storeProcedure, " ::: Error al ejecutar un sp de varias variables de salida ::: ", e, parametros);
        }catch(Exception e){
            close();
            throw daoException(storeProcedure, " ::: Error de programacion al ejecutar un sp de varias variables de salida ::: ", e, parametros);
        } 
        return respuesta;
    }
    
    public void execute(String storeProcedure, Object parametros[])throws DaoException{
    
    	String sql = nombreStoreProcedure(storeProcedure, parametros.length);
    	try{
    		setearVariableEntrada(sql, parametros);
    		cstm.execute();
    	}catch(SQLException e){
        close();
        throw daoException(storeProcedure, " ::: Error al ejecutar un procedimiento simple ::: ", e, parametros);
    	}
    }
    
    public void executeException(String storeProcedure, Object parametros[])throws SQLException {    
    	String sql = nombreStoreProcedure(storeProcedure, parametros.length);
    	setearVariableEntrada(sql, parametros);
    	cstm.execute();
    }
  
}